#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <pthread.h>
#include <unistd.h>
#include <memory>
#include "Thread.hpp"

using namespace std;

// // 添加__thread，可以将一个内置类型设置为线程局部存储
// __thread int g_val = 100;

// string changeId(const pthread_t &thread_id)
// {
//     char tid[128];
//     snprintf(tid, sizeof(tid), "0x%x", thread_id);
//     return tid;
// }

// // 线程分离
// void *start_routine(void *args)
// {
//     string threadname = static_cast<const char *>(args);
//     // pthread_detach(pthread_self());     // 设置自己为分离状态

//     int cnt = 5;
//     while (true)
//     {
//         cout << threadname << " running ... : " << changeId(pthread_self()) << " g_val: " << g_val << " &g_val: " << &g_val << endl;
//         sleep(1);
//         g_val++;
//     }

//     return nullptr;
// }

void *thread_run(void* args)
{
    string work_type = static_cast<const char*>(args);
    while(true)
    {
        cout << "我是一个新线程，我正在做: " << work_type <<endl;
        sleep(1);
    }
}

int main()
{
    std::unique_ptr<Thread> thread1(new Thread(thread_run, (void*)"hellothread", 1));
    std::unique_ptr<Thread> thread2(new Thread(thread_run, (void*)"countthread", 2));
    std::unique_ptr<Thread> thread3(new Thread(thread_run, (void*)"logthread", 3));
    thread1->start();
    thread2->start();
    thread3->start();

    thread1->join();
    thread2->join();
    thread3->join();

    return 0;


    
    // pthread_t tid;
    // pthread_create(&tid, nullptr, start_routine, (void *)"thread 1");
    // string main_id = changeId(pthread_self());
    // pthread_detach(tid);

    // cout << "main thread running ... new thread id: " << changeId(tid) << " main thread id: " << main_id << endl;

    // // sleep(2);
    // // // 线程默认是joinable，如果设置了分离状态，就不能进行等待
    // // int n = pthread_join(tid, nullptr);
    // // cout << "result: " << n << " : " << strerror(n) << endl; 

    // while(true)
    // {
    //     cout << "main thread running ... new thread id: " <<\
    //          changeId(tid) << " main thread id: " << main_id << " g_val: " << g_val << " &g_val: " << &g_val << endl;
    //     sleep(1);
    // }

    // return 0;
}

// #define NUM 10

// class ThreadData
// {
// public:
//     int number;
//     pthread_t tid;
//     char namebuffer[64];
// };

// class ThreadReturn
// {
// public:
//     int exit_code;
//     int exit_result;
// };

// // 1、被多个线程使用，可重入状态
// // 2、可重入函数
// // 3、函数内定义的变量都叫做局部变量，具有临时性 -- 每个线程都有一个独立的栈结构
// void *start_routine(void *args)
// {
//     // sleep(1);
//     // 一个线程如果出现异常，会影响其它线程
//     // 线程异常 -> 发送进程信号 -> 进程中断
//     ThreadData *td = static_cast<ThreadData *>(args); // 安全的进行强制类型转化
//     int cnt = 10;
//     while (cnt)
//     {
//         cout << "cnt: " << cnt << " &cnt: " << &cnt << endl;
//         cnt--;
//         sleep(1);
//         // return nullptr;         // return终止
//         // pthread_exit(nullptr);  // pthread_exit终止
//         // exit(0);        // 不能用来终止线程，会直接终止掉进程！任何一个执行流调用exit都会让整个进程退出
//         //  cout << "new thread create success, name: " << td->namebuffer << " cnt: " << cnt-- << endl;
//         //  int *p = nullptr;
//         //  *p = 0;      线程发生错误，从而导致进程出错中断
//     }

//     // 线程如何终止
//     // delete td;
//     // pthread_exit(nullptr); // pthread_exit终止

//     // return nullptr;     // 线程函数结束，return的时候，线程就算终止了

//     // return (void*)td->number;       // void* tmp = (void*)td->number
//     // return (void*)20250319;

//     ThreadReturn *tr = new ThreadReturn();
//     tr->exit_code = 1;
//     tr->exit_result = 111;

//     //return (void *)tr;
//     return (void*)100;
// }

// int main()
// {
//     // 任何语言，在linux中如果要实现多线程，必定要使用pthread库
//     // c++多线程，本质是对pthread库的封装
//     // std::thread t1(/*新进程执行程序函数名*/start_routine);
//     // while(true)
//     // {
//     //     std::cout<<"我是主线程..." << std::endl;
//     //     sleep(1);
//     // }
//     // t1.join();

//     // 1、创建一批线程
//     vector<ThreadData *> threads;
//     for (int i = 0; i < NUM; ++i)
//     {
//         // 创建新线程的方法：
//         // 1.常规（这种方法不安全）
//         // pthread_t tid;
//         // char namebuffer[64];
//         // snprintf(namebuffer, sizeof(namebuffer), "%s:%d", "thread", i);
//         // pthread_create(&tid, nullptr, start_routine, (void*)"thread one");
//         // pthread_create(&tid, nullptr, start_routine, (void*)namebuffer);
//         // sleep(1);         //  这里没有sleep的话主线程和新线程的运行顺序是随机的，这就会导致一直执行主线程从而namebuffer的里的内容会被重复写入

//         // 2.
//         ThreadData *td = new ThreadData();
//         td->number = i + 1;
//         snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i);
//         pthread_create(&td->tid, nullptr, start_routine, td);
//         threads.push_back(td);
//     }

//     for (auto &iter : threads)
//     {
//         cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " success" << endl;
//     }
//     // 线程是可以被cancel取消的，要注意的是：取消的前提是线程需要先被跑起来（运行起来）
//     // 线程如果是被取消的，退出码：-1 PTHREAD_CANCELED
//     sleep(5);
//     for(int i = 0; i < threads.size() / 2; ++i)
//     {
//         pthread_cancel(threads[i]->tid);
//         cout << "pthread_cancel: " << threads[i]->namebuffer << " success" << endl;
//     }

//     for (auto &iter : threads)
//     {
//         void *ret = nullptr;
//         // 线程没有对应的退出信号？ 没有，如果有异常的话，整个进程都会退出
//         // pthread_join:默认会成功，不关心异常问题
//         int n = pthread_join(iter->tid, (void **)&ret); // 函数内部二级指针void** retp接收      *retp = return （void*）td->number
//         assert(n == 0);
//         cout << "join: " << iter->namebuffer << " success, exit_code: " << (long long)ret << endl;
//         delete iter;
//     }

//     cout << "main thread quit" << endl;

//     return 0;

//     // while (true)
//     // {
//     //     cout << "new thread create success, name: main thread" << endl;
//     //     sleep(1);
//     // }

//     // pthread_t id;
//     // pthread_create(&id, nullptr, start_routine, (void*)"thread new");

//     // while (true)
//     // {
//     //     cout << "new thread create success, name: main thread" << endl;
//     //     sleep(1);
//     // }
// }

// int g_val = 100;

// const string& fun()
// {
//     return "我是一个独立的方法";
// }

// // 新线程
// void* thread_routine(void* args)
// {
//     const char* name = (const char*) args;
//     while (true)
//     {
//         cout << "我是新线程，我正在运行! name: " << name << ":" << g_val++ << endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t tid;
//     int n = pthread_create(&tid, NULL, thread_routine, (void*)"thread one");
//     assert(0 == n);
//     (void)n;

//     // 主线程
//     while (true)
//     {
//         char tidbuffer[64];
//         snprintf(tidbuffer,sizeof(tidbuffer), "0x%x", tid);
//         cout << "我是主线程，我正在运行! 我创建出来的线程的tid: " << tidbuffer <<  ":" << g_val << endl;
//         sleep(1);
//     }

//     return 0;
// }